package com.hzhq.contract.controller;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.hzhq.contract.bean.dto.UserDTO;
import com.hzhq.contract.bean.entity.User;
import com.hzhq.contract.bean.vo.UserVO;
import com.hzhq.contract.convert.UserConvertBasic;
import com.hzhq.contract.result.Result;
import com.hzhq.contract.result.ResultEnum;
import com.hzhq.contract.service.UserService;
import com.hzhq.contract.status.DefaultValue;
import com.hzhq.contract.util.Page2ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;


import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @author hzhq
 * @create 2021/3/23 8:56 下午
 * @email hzhq1255@163.com
 */
@Slf4j
@Api(tags = "用户管理")
@CrossOrigin
@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private static final String DEFAULT_PASSWORD = "123456";

    @Autowired
    UserService userService;




    @ApiOperation(value = "获取用户角色信息")
    @ResponseBody
    @RequestMapping(value = "/user/{userId}/role",method = RequestMethod.GET)
    public Result<Object> getUserRoleInfo(){

        return null;
    }


    @ApiOperation(value = "用户列表")
    @ResponseBody
    @GetMapping
    private Result<Object> getAllUserList(){
        return userService.getAllUserList();
    }

    @ApiOperation(value = "用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage",value = "当前页",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize",value = "每页个数",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/currentPage/{currentPage}/pageSize/{pageSize}",method = RequestMethod.GET)
    private Result<Object> getAll(@PathVariable("currentPage") @NotNull Integer currentPage,
                          @PathVariable("pageSize") @NotNull Integer pageSize){
        // 默认以注册时间排序
        Pageable pageable = Page2ResultUtil.buildPageableByParam(
                        currentPage, pageSize,Sort.by(Sort.Direction.DESC,"registerTime"));
        if (null == pageable){
            return Result.build(ResultEnum.PAGE_PARAM_ERROR);
        }
        Page<UserDTO> userPage = userService.getAll(pageable);
        return Result.successWithData(Page2ResultUtil.getPageData(userPage.map(UserConvertBasic.INSTANCE::dtoToVo)));
    }

    @ApiOperation("保存用户")
    @ResponseBody
    @RequestMapping(value = "/save",method = RequestMethod.POST)
    private Result<Object> saveUser(@RequestParam("username")  @NotNull String username,
                                    @RequestParam(value = "phone",required = false)  String phone,
                                    @RequestParam(value = "password1",required = false)  String password1,
                                    @RequestParam(value = "password2",required = false) String password2,
                                    @RequestParam(value = "isDeleted", defaultValue = "false") boolean isDeleted,
                                    @RequestParam(value = "isRest",defaultValue = "false") boolean isRest){
        UserDTO currentUser = userService.getOneByName(username);
        if (null == currentUser){
            return Result.errorWithMsg("该用户不存在");
        }
        if (isRest){
            currentUser.setPassword(SecureUtil.md5(DEFAULT_PASSWORD));
            userService.save(currentUser);
            return Result.successWithMsg("重置密码成功");
        } else {
            if (isDeleted){
                currentUser.setDeleted(DefaultValue.DELETED);
                System.out.println(JSONObject.toJSONString(userService.save(currentUser)));
                return Result.successWithMsg("删除成功");
            }else {
                if ( null != phone && !"".equals(phone) ){
                    currentUser.setPhone(phone);
                }
                if (password1 != null && password2 != null){
                    if (password1.equals(password2)) {
                        currentUser.setPassword(SecureUtil.md5(password1));
                        userService.save(currentUser);
                        return Result.successWithMsg("密码修改成功");
                    }
                    return Result.errorWithMsg("两次输入的密码不一致");
                }
                userService.save(currentUser);
                return Result.successWithMsg("修改成功");
            }

        }
    }

    @ApiOperation(value = "搜索用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keyword",value = "关键字",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "currentPage",value = "当前页",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize",value = "每页个数",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer")
    })
    @RequestMapping(value = "/search/currentPage/{currentPage}/pageSize/{pageSize}",method = RequestMethod.GET)
    private Result<Object> searchUserPage(@RequestParam(value = "keyword",required = false) @NotNull String keyword,
                                  @PathVariable("currentPage") @NotNull Integer currentPage,
                                  @PathVariable("pageSize") @NotNull Integer pageSize){
        UserDTO userExample = new UserDTO();
        userExample.setUsername(keyword);
        userExample.setPhone(keyword);
        userExample.setDeleted(DefaultValue.NOT_DELETED);
        Page<UserVO> userVOPage = userService.searchAllPages(userExample,currentPage,pageSize).map(UserConvertBasic.INSTANCE::dtoToVo);
        return Result.successWithData(Page2ResultUtil.getPageData(userVOPage));
    }

    @ApiOperation(value = "搜索用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keyword",value = "关键字",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "currentPage",value = "当前页",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize",value = "每页个数",paramType = "path",dataTypeClass = Integer.class, dataType = "Integer")
    })
    @RequestMapping(value = "/search/query/currentPage/{currentPage}/pageSize/{pageSize}",method = RequestMethod.GET)
    private Result<Object> searchUserPageByQuery(@RequestParam(value = "keyword",required = false) String keyword,
                                                 @PathVariable("currentPage") @NotNull Integer currentPage,
                                                 @PathVariable("pageSize") @NotNull Integer pageSize){
        final Query query = new Query();
        final Criteria criteria = new Criteria();
        List<Criteria> ands = new ArrayList<>();
        List<Criteria> ors = new ArrayList<>();
        if (null != keyword){
            ors.add(Criteria.where(User.USERNAME_FIELD).regex("^.*"+ keyword +".*$"));
            ors.add(Criteria.where(User.PHONE_FIELD).regex("^.*"+keyword+".*$"));
            criteria.orOperator(ors.toArray(Criteria[]::new));
        }
        ands.add(Criteria.where(User.DELETED_FIELD).is(DefaultValue.NOT_DELETED));
        criteria.andOperator(ands.toArray(Criteria[]::new));
        query.addCriteria(criteria);
        Page<UserVO> userVOPage =  userService.searchAllPages(query,currentPage,pageSize).map(UserConvertBasic.INSTANCE::dtoToVo);
        return Result.successWithData(Page2ResultUtil.getPageData(userVOPage));
    }

    @ApiOperation(value = "用户申请权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "申请的用户",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "role",value = "部门职位 现在有 管理员 录入人员 审批人员",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "depart",value = "部门名",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "admin",required = false,value = "授予权限的管理员",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "type",required = false,value = "管理员类型 0 系统管理员 1 部门管理员",paramType = "query",dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "passed",value = "通过状态 -1 拒绝 0 未通过 1 已通过",paramType = "query",dataTypeClass = Integer.class,dataType = "Integer")
    })
    @RequestMapping(value = "/applicant",method = RequestMethod.POST)
    private Result<Object> applicantRole(@RequestParam("username") @NotNull String username,
                                         @RequestParam("role") @NotNull  String role,
                                         @RequestParam("depart") @NotNull String depart,
                                         @RequestParam(value = "admin",required = false)  String admin,
                                         @RequestParam(value = "type",required = false)  Integer type,
                                         @RequestParam(value = "passed",required = false)  Integer passed){

        return userService.applicantRole(username,role,depart,admin,type,passed);
    }


    @ApiOperation(value = "用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用户名",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "password",value = "密码",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "role",value = "系统管理员 0 普通用户 1",paramType = "query",dataTypeClass = Integer.class, dataType = "Integer")
    })
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    private Result<Object> loginCheck(@RequestParam("username") @NotBlank String username,
                              @RequestParam("password") @NotBlank String password,
                              @RequestParam("type") @NotBlank Integer type){
        if (type == 1){
            log.info("普通用户 {} 正在登录",username);
        }
        if (type == 0){
            log.info("系统管理员 {} 正在登录",username);
        }
        return userService.loginCheck(username,password,type);

    }


    /**
     *
     * @param username
     * @param password1
     * @param password2
     * @param phone
     * @return
     */
    @ApiOperation(value = "用户注册",httpMethod = "POST")
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用户名",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "password1",value = "密码1",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "password2",value = "密码2",paramType = "query",dataTypeClass = String.class, dataType = "String"),
            @ApiImplicitParam(name = "phone",value = "手机号",paramType = "query",dataTypeClass = String.class, dataType = "String"),
    })
    @ResponseBody
    private Result<Object> registerUser(@RequestParam("username") @NotNull String username,
                                        @RequestParam("password1") @NotNull String password1,
                                        @RequestParam("password2") @NotNull String password2,
                                        @RequestParam("phone") @NotNull String phone)  {
        UserDTO user = new UserDTO();
        try {
            if (!password1.equals(password2)) {
                return Result.build(ResultEnum.USER_REGISTER_PWD_ERROR);
            }
            user.setUsername(username);
            user.setPassword(SecureUtil.md5(password1));
            user.setPhone(phone);
            user.setRegisterTime(new Date());
            user.setDeleted(DefaultValue.NOT_DELETED);
        }catch (Exception e){
            e.printStackTrace();
            return Result.build(ResultEnum.NULL_ERROR);
        }
        return userService.registerUser(user);
    }




}
